
package com.laolei.core.model;

import java.io.Serializable;
import java.util.List;

public class PageInfo<T> implements Serializable {
	private static final long serialVersionUID = 1L;
	// 当前页
	private int pageNum;
	// 每页的数量
	private int pageSize;
	// 当前页的数量
	private int size;
	// 排序
	private String orderBy;

	// 由于startRow和endRow不常用，这里说个具体的用法
	// 可以在页面中"显示startRow到endRow 共size条数据"

	// 当前页面第一个元素在数据库中的行号
	private int startRow;
	// 当前页面最后一个元素在数据库中的行号
	private int endRow;
	// 总记录数
	private long total;
	// 总页数
	private int pages;
	// 结果集
	private List<T> list;

	// 第一页
	private int firstPage;
	// 前一页
	private int prePage;
	// 下一页
	private int nextPage;
	// 最后一页
	private int lastPage;

	// 是否为第一页
	private boolean isFirstPage = false;
	// 是否为最后一页
	private boolean isLastPage = false;
	// 是否有前一页
	private boolean hasPreviousPage = false;
	// 是否有下一页
	private boolean hasNextPage = false;
	// 导航页码数
	private int navigatePages;
	// 所有导航页号
	private int[] navigatepageNums;

	/**
	 * 包装Page对象
	 * 
	 * @param pageNum
	 *            当前第几页
	 * @param pageSize
	 *            每页数据量
	 * @param total
	 *            总数据量
	 * @param list
	 *            page结果
	 * @param list
	 */
	public PageInfo(int pageNum, long total, List<T> list) {
		this(pageNum, 10, total, list, null);
	}

	/**
	 * 包装Page对象
	 * 
	 * @param pageNum
	 *            当前第几页
	 * @param pageSize
	 *            每页数据量
	 * @param total
	 *            总数据量
	 * @param list
	 *            page结果
	 * @param list
	 */
	public PageInfo(int pageNum, long total, List<T> list, String orderBy) {
		this(pageNum, 10, total, list, orderBy);
	}

	/**
	 * 包装Page对象
	 * 
	 * @param pageNum
	 *            当前第几页
	 * @param pageSize
	 *            每页数据量
	 * @param total
	 *            总数据量
	 * @param list
	 *            page结果
	 * @param list
	 */
	public PageInfo(int pageNum, int pageSize, long total, List<T> list, String orderBy) {
		this(pageNum, pageSize, total, list, 8, orderBy);
	}

	/**
	 * 包装Page对象
	 * 
	 * @param pageNum
	 *            当前第几页
	 * @param pageSize
	 *            每页数据量
	 * @param total
	 *            总数据量
	 * @param list
	 *            page结果
	 * @param orderBy
	 * @param navigatePages
	 *            导航中的页码数量
	 */
	public PageInfo(int pageNum, int pageSize, long total, List<T> list, int navigatePages, String orderBy) {
		if (pageNum < 0)
			pageNum = 0;
		this.pageNum = pageNum;
		this.pageSize = pageSize;
		this.navigatePages = navigatePages;

		this.orderBy = orderBy;
		this.list = list;
		this.size = list == null ? 0 : list.size();
		this.total = total;
		this.pages = (int) Math.ceil(total / (this.pageSize * 1.0));
		this.startRow = (this.pageNum) * this.pageSize;
		this.endRow = this.startRow + this.size;

		// 计算导航页
		calcNavigatepageNums();
		// 计算前后页，第一页，最后一页
		calcPage();
		// 判断页面边界
		judgePageBoudary();
	}

	/**
	 * 计算导航页
	 */
	private void calcNavigatepageNums() {
		// 当总页数小于或等于导航页码数时
		if (pages <= navigatePages) {
			navigatepageNums = new int[pages];
			for (int i = 0; i < pages; i++) {
				navigatepageNums[i] = i + 1;
			}
		} else { // 当总页数大于导航页码数时
			navigatepageNums = new int[navigatePages];
			int startNum = pageNum - navigatePages / 2;
			int endNum = pageNum + navigatePages / 2;

			if (startNum < 1) {
				startNum = 1;
				// (最前navigatePages页
				for (int i = 0; i < navigatePages; i++) {
					navigatepageNums[i] = startNum++;
				}
			} else if (endNum > pages) {
				endNum = pages;
				// 最后navigatePages页
				for (int i = navigatePages - 1; i >= 0; i--) {
					navigatepageNums[i] = endNum--;
				}
			} else {
				// 所有中间页
				for (int i = 0; i < navigatePages; i++) {
					navigatepageNums[i] = startNum++;
				}
			}
		}
	}

	/**
	 * 计算前后页，第一页，最后一页
	 */
	private void calcPage() {
		if (navigatepageNums != null && navigatepageNums.length > 0) {
			firstPage = navigatepageNums[0];
			lastPage = navigatepageNums[navigatepageNums.length - 1];
			if (pageNum > 1) {
				prePage = pageNum - 1;
			}
			if (pageNum < pages) {
				nextPage = pageNum + 1;
			}
		}
	}

	/**
	 * 判定页面边界
	 */
	private void judgePageBoudary() {
		isFirstPage = pageNum <= 1;
		isLastPage = pageNum >= pages;
		hasPreviousPage = pageNum > 1;
		hasNextPage = pageNum < pages;
	}

	public int getPageNum() {
		return pageNum;
	}

	public void setPageNum(int pageNum) {
		this.pageNum = pageNum;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public String getOrderBy() {
		return orderBy;
	}

	public void setOrderBy(String orderBy) {
		this.orderBy = orderBy;
	}

	public int getStartRow() {
		return startRow;
	}

	public void setStartRow(int startRow) {
		this.startRow = startRow;
	}

	public int getEndRow() {
		return endRow;
	}

	public void setEndRow(int endRow) {
		this.endRow = endRow;
	}

	public long getTotal() {
		return total;
	}

	public void setTotal(long total) {
		this.total = total;
	}

	public int getPages() {
		return pages;
	}

	public void setPages(int pages) {
		this.pages = pages;
	}

	public List<T> getList() {
		return list;
	}

	public void setList(List<T> list) {
		this.list = list;
	}

	public int getFirstPage() {
		return firstPage;
	}

	public void setFirstPage(int firstPage) {
		this.firstPage = firstPage;
	}

	public int getPrePage() {
		return prePage;
	}

	public void setPrePage(int prePage) {
		this.prePage = prePage;
	}

	public int getNextPage() {
		return nextPage;
	}

	public void setNextPage(int nextPage) {
		this.nextPage = nextPage;
	}

	public int getLastPage() {
		return lastPage;
	}

	public void setLastPage(int lastPage) {
		this.lastPage = lastPage;
	}

	public boolean isIsFirstPage() {
		return isFirstPage;
	}

	public void setIsFirstPage(boolean isFirstPage) {
		this.isFirstPage = isFirstPage;
	}

	public boolean isIsLastPage() {
		return isLastPage;
	}

	public void setIsLastPage(boolean isLastPage) {
		this.isLastPage = isLastPage;
	}

	public boolean isHasPreviousPage() {
		return hasPreviousPage;
	}

	public void setHasPreviousPage(boolean hasPreviousPage) {
		this.hasPreviousPage = hasPreviousPage;
	}

	public boolean isHasNextPage() {
		return hasNextPage;
	}

	public void setHasNextPage(boolean hasNextPage) {
		this.hasNextPage = hasNextPage;
	}

	public int getNavigatePages() {
		return navigatePages;
	}

	public void setNavigatePages(int navigatePages) {
		this.navigatePages = navigatePages;
	}

	public int[] getNavigatepageNums() {
		return navigatepageNums;
	}

	public void setNavigatepageNums(int[] navigatepageNums) {
		this.navigatepageNums = navigatepageNums;
	}

	@Override
	public String toString() {
		final StringBuffer sb = new StringBuffer("PageInfo{");
		sb.append("pageNum=").append(pageNum);
		sb.append(", pageSize=").append(pageSize);
		sb.append(", size=").append(size);
		sb.append(", startRow=").append(startRow);
		sb.append(", endRow=").append(endRow);
		sb.append(", total=").append(total);
		sb.append(", pages=").append(pages);
		sb.append(", list=").append(list);
		sb.append(", firstPage=").append(firstPage);
		sb.append(", prePage=").append(prePage);
		sb.append(", nextPage=").append(nextPage);
		sb.append(", lastPage=").append(lastPage);
		sb.append(", isFirstPage=").append(isFirstPage);
		sb.append(", isLastPage=").append(isLastPage);
		sb.append(", hasPreviousPage=").append(hasPreviousPage);
		sb.append(", hasNextPage=").append(hasNextPage);
		sb.append(", navigatePages=").append(navigatePages);
		sb.append(", navigatepageNums=");
		if (navigatepageNums == null)
			sb.append("null");
		else {
			sb.append('[');
			for (int i = 0; i < navigatepageNums.length; ++i)
				sb.append(i == 0 ? "" : ", ").append(navigatepageNums[i]);
			sb.append(']');
		}
		sb.append('}');
		return sb.toString();
	}
}
